﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Net;
using System.IO;

namespace DaBot
{
    class Program
    {
        private static string nick = "Brenden";
        private static string mimic;
        private static bool bmimic;
        private static int timeout = 1000;
        private static bool bFight = false;
        public static c contestantOne, contestantTwo;
        private static string fightChannel;
        private static string[] weapons = new string[50];
        private static Thread fightThread;
        private static CSIRC IRC = new CSIRC();
        static void Main(string[] args)
        {
            IRC.RegisterExceptionCallback(OnException);
            IRC.RegisterMessageCallback(OnMessage);
            IRC.RegisterKickCallback(OnKick);
            IRC.RegisterJoinCallback(OnJoin);
            IRC.RegisterPartCallback(OnPart);
            IRC.RegisterQuitCallback(OnQuit);
            IRC.RegisterModeCallback(OnMode);
            IRC.RegisterRawRecvStringCallback(OnRecvdStr);
            IRC.RegisterRawSentStringCallblack(OnSentStr);
            IRC.RegisterUnhandledResponseCallback(OnUnhandledResponse);
            IRC.RegisterTopicCallback(OnTopic);
            IRC.Connect("hyperion.kaosnetworks.com", 6667, null, nick, "Brenden", "goml");
            IRC.WaitForConnected();
            IRC.JoinChannel("#sourced");
            //IRC.JoinChannel("#kaos");
        }
        private static void OnUnhandledResponse(string str)
        {

        }
        private static void OnRecvdStr(string recvstr)
        {
            //Console.BackgroundColor = ConsoleColor.Green;
            Console.WriteLine(recvstr);
        }
        private static void OnSentStr(string sentstr)
        {

        }
        private static void OnTopic(string channel, string nick, string newtopic)
        {
            Console.WriteLine("Topic changed on "+channel + " by " + nick + ": ");
        }
        private static void OnMode(string channel, string setby, string modes)
        {
            if (setby == "StatBot")
            {
                if (modes.StartsWith("-"))
                {
                    IRC.SendMessage(channel, "There goes StatBot being a faggot and removing people's ops/voices again");
                }
            }
        }
        private static void OnException(Exception e)
        {

        }
        private static void OnMessage(string channel, string text, string user, string hostname)
        {
            Console.BackgroundColor = ConsoleColor.Red;
            Console.WriteLine(channel + " " + user + ": " + text);
            string[] local = text.Split(' ');
            string textd = (string)local.GetValue(0);
            if( textd.ToLower() == "!myhost" ) IRC.SendMessage(channel, hostname);
            if (textd.ToLower() == "!b&" && user.ToLower() == "ox90")
            {
                IRC.SendMessage(channel, "lol");
                IRC.BanUser(channel, (string)((Array)text.Split(' ')).GetValue(1));
            }
            if (textd == "!kik" && user == "Ox90")
            {
                if (text.Length <= "`kick".Length)//YES, IT MIGHT BE A GOOD IDEA TO GET THE LENGTH OF THE STRING BEFORE SPLITTING IT.
                {
                    IRC.SendMessage(channel, "Stop wasting my time, at least give me a nick to kick.");//If not, do what every other bot does, output an insulting message.
                    return;//For efficiency.
                }
                string[] kicks = text.Split(' ');//SPLIT STRING INTO SUBSTRINGS THAT ARE SEPERATED USING SPACE
                string kicknick = (string)kicks.GetValue(1);//1 CONTAINS THE USER TO KICK
                if (kicks.Length >= 3)
                {
                    string reason = text.Remove(0, 6 + kicknick.Length + 1);//SINCE REASON CAN HAVE SPACES, WE MUST DO SOME MAGICAL TRICKERY (get the length of the command + nick then remove the first n characters from the string)
                    IRC.KickUser(channel, kicknick, reason);//LET THE KICKING COMMENCE
                    return;//For efficiency.
                }
                if(kicks.Length < 2)//They do not want to give a reason, so just put requested by the user
                {
                    IRC.KickUser(channel, kicknick, "Requested by " + user);//LET THE KICKING COMMENCE
                    return;//For efficiency.
                }
            }
            if (textd == "!raw" && user == "Ox90" && channel == nick)
            {
                text = text.Remove(0, 5);
                IRC.Raw(text);
                return;
            }
            if (textd == "!echo" && user == "Ox90")
            {
                text = text.Remove(0, 6);
                IRC.SendMessage(channel, text);
                return;
            }
            if (user == "Muhammet")
            {
                IRC.SendMessage(channel,text);
            }
            if (textd == "!nick" && user == "Ox90")
            {
                string[] nicks = text.Split(' ');
                string newnick = (string)nicks.GetValue(1);
                IRC.Raw("NICK :" + newnick);
            }
            if (textd == "!action" && user == "Ox90")
            {
                Console.WriteLine("watt");
                text = text.Remove(0, 8);
                IRC.Action(channel, text);
            }
            if (textd == "!join" && user == "Ox90")
            {
                text = text.Remove(0, 6);
                IRC.JoinChannel(text);
                return;
            }
            if (textd == "!part" && user == "Ox90")
            {
                IRC.PartChannel(text.Remove(0, 6));
                return;
            }
            if (textd == "!statbot")
            {
                string[] what = new string[10];
                what[0] = "Statbot is a dumb racist bot";
                what[1] = "Statbot has jelly for brains";
                what[2] = "Statbot is useless";
                what[3] = "Statbot is generally annoying";
                what[4] = "Statbot is the cancer of IRC";
                Random r = new Random();
                int ran = r.Next(0, 4);
                IRC.SendMessage(channel, what[ran]);
                return;
            }
            if (textd.ToLower() == "!base64enc")
            {
                IRC.SendMessage(channel, Convert.ToBase64String((byte[])System.Text.Encoding.UTF8.GetBytes((string)(text.Split(' ')).GetValue(1))));
            }
            if (textd.ToLower() == "!base64dec")
            {
                IRC.SendMessage(channel, System.Text.Encoding.UTF8.GetString(Convert.FromBase64String((string)(text.Split(' ')).GetValue(1))));
            }
            if (textd.ToLower().Contains("www.youtube.com"))
            {
                string url = textd;
                if (!textd.Contains("http://"))
                {
                    url = "http://" + textd;
                }
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
                HttpWebResponse res = (HttpWebResponse)req.GetResponse();
                StreamReader strread = new StreamReader(res.GetResponseStream());
                string read = strread.ReadLine();
                string title = null;
                while (true)
                {
                    read = strread.ReadLine();
                    if (read.ToLower().Contains("<meta name=\"title\""))
                    {
                        string[] wats = read.Split('"');
                        title = (string)wats.GetValue(3);
                        break;
                    }
                }
                IRC.SendMessage(channel, "Title: \"" + title + "\"");
            }
                
            if (text.Contains(nick))
            {
                IRC.SendMessage(channel, "wat");
            }
            if (user == mimic && bmimic)
            {
                IRC.SendMessage(channel, text);
                return;
            }
            if (textd == "!gline" && user == "Ox90")
            {
                string[] locale = text.Split(',');
            }
            if (textd == "!fight" && !bFight && user == "Ox90")
            {
                contestantOne.HP = 100;
                contestantTwo.HP = 100;
                //Split the string using a space as a token.
                string[] splitted = text.Split(' ');
                //Parse the contestants
                contestantOne.name  = (string)splitted.GetValue(1);
                contestantTwo.name = (string)splitted.GetValue(2);
                fightChannel = channel;
                //Split the string using comma as a token
                //splitted = text.Split(',');
                //The first weapon needs some special parsing
                //weapons[0] = ((string)splitted.GetValue(0)).Remove(0,"!fight ".Length + contestantOne.Length + contestantTwo.Length + 2);
                //Now we can parse the rest using a for loop :D
                //for (uint i = 1; i < splitted.Length; i++)
                //{
                //    weapons[i] = (string)splitted.GetValue(i);
                //}
                //Create a new thread for dealing with this feature otherwise thread execution will be halted and the bot will lag
                bFight = true;
                fightThread = new Thread(FightThread);
                fightThread.Start();
            }
            if (textd == "!stopfight")
            {
                bFight = false;
            }
            if(textd == "!bset")
            {
                string[] wat = text.Split(' ');
                string cmd = (string)wat.GetValue(1);
                if( cmd == "timeout")
                {
                    timeout = Convert.ToInt32(wat.GetValue(2));
                }
            }
            if (textd == "!gethealth")
            {
                string[] wat = text.Split(' ');
                string healthof = (string)wat.GetValue(1);
                if (healthof.ToLower() == contestantOne.name.ToLower())
                {
                    IRC.SendMessage(channel, contestantOne.name + "'s health is " + contestantOne.HP);
                }
                if (healthof.ToLower() == contestantTwo.name.ToLower())
                {
                    IRC.SendMessage(channel, contestantTwo.name + "'s health is " + contestantTwo.HP);
                }
            }
            if (textd.ToLower() == "boop")
            {
                IRC.SendMessage(channel, "beep");
                Thread.Sleep(1000);
            }
        }
        private static Random regHit = new Random();
        private static Random crtiHit = new Random();
        private static string Hit(c Contestant, c Target)
        {
            int Hit, wepID, hitType;
            Random weaponID = new Random();
            wepID = weaponID.Next(0, weapons.Length);
            Random HitSpec = new Random();
            hitType = HitSpec.Next(0, 10);
            if (Target.HP <= 0)
            {
                bFight = false;
                return Target.name + " is dead! " + Contestant.name + " wins! " + Contestant.name + " still has " + Contestant.HP + " left!";
            }
            if (hitType < 3)
            {
                Hit = 0;
                return Contestant.name + " attempts to hit " + Target.name + " but misses! 0 Damage is dealt!";
            }
            if (hitType >= 3 && hitType < 8)
            {
                
                Hit = regHit.Next(1, 50);
                Target.HP = Target.HP - Hit;
                return Contestant.name + " hit " + Target.name + /*" with a " + weapons[regHit.Next(0,weapons.Length)] +*/ " and dealt " + Hit + " damage!";
            }
            if (hitType >= 8)
            {
                
                Hit = crtiHit.Next(25, 200);
                Target.HP = Target.HP - Hit;
                return Contestant.name + " critically hit " + Target.name /*+ " with a " + weapons[regHit.Next(0, weapons.Length)] */+ " and dealt " + Hit + " damage!";
            }
            return "Error";
            
        }
        private static void FightThread()
        {
            while (bFight)
            {
                IRC.SendMessage(fightChannel, Hit(contestantOne, contestantTwo));
                Thread.Sleep(timeout);
                IRC.SendMessage(fightChannel, Hit(contestantTwo, contestantOne));
                Thread.Sleep(timeout);
            }

        }
        private static void OnKick(string channel, string kicker, string kicked, string reason)
        {
            Console.WriteLine(kicked + " was kicked from " + channel + " by " + kicker + "(" + reason + ")");
            if (kicked == nick)
            {
                IRC.JoinChannel(channel);
            }
        }
        private static void OnJoin(string channel, string user)
        {
            Console.WriteLine(user + " joined " + channel);
            if (user == "Ox90" && channel == "#sourced")
            {
                IRC.SendMessage(channel, "Hello master!");
                return; ;
            }
        }
        private static void OnPart(string channel, string user, string reason)
        {
            Console.WriteLine(user + " left " + channel + "(" + reason + ")");
            if (user == "Brandon" && channel == "#sourced")
            {
                IRC.SendMessage(channel, "*sob*, Brandon has left because " + reason);
            }
        }
        private static void OnQuit(string user, string message)
        {
            Console.WriteLine(user + "Quit(" + message + ")");
        }
    }
    struct c
    {
        public string name;
        public int HP;
    }
}
